package factorytest.iflytek.com.einkiflytekfactorytest.factorytestui;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import factorytest.iflytek.com.einkiflytekfactorytest.BluetoothBondManager.BluetoothBondManager;
import factorytest.iflytek.com.einkiflytekfactorytest.BluetoothBondManager.OnBluetoothEnabledListener;
import factorytest.iflytek.com.einkiflytekfactorytest.FTFloatWindowService;
import factorytest.iflytek.com.einkiflytekfactorytest.R;
import factorytest.iflytek.com.einkiflytekfactorytest.ViewDialogFragment;
import factorytest.iflytek.com.einkiflytekfactorytest.common.FTUtils;
import factorytest.iflytek.com.einkiflytekfactorytest.common.ForeLightCtrl;
import factorytest.iflytek.com.einkiflytekfactorytest.common.LedCtrl;
import factorytest.iflytek.com.einkiflytekfactorytest.common.PermissionManager;
import factorytest.iflytek.com.einkiflytekfactorytest.config.EinkProperty;
import factorytest.iflytek.com.einkiflytekfactorytest.config.HtfyunBuildConfig;
import factorytest.iflytek.com.einkiflytekfactorytest.device.DeviceAttr;
import factorytest.iflytek.com.einkiflytekfactorytest.engineer_test.FragmentES7210;
import factorytest.iflytek.com.einkiflytekfactorytest.engineer_test.FragmentES7210_MonoTest;
import factorytest.iflytek.com.einkiflytekfactorytest.engineer_test.FragmentES7210_RecordAndPlay;
import factorytest.iflytek.com.einkiflytekfactorytest.engineer_test.OnBtnResultForES7210;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.DebugLog;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.FileReadWrite;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.UsefulUtils;

public class FactoryPCBAActivity extends FactoryBaseActivity implements OnBluetoothEnabledListener, View.OnClickListener {

    private PCBATestBtnView btnTPFinger;
    private PCBATestBtnView btnTPElectric;

    private Button btnLedOk;
    private Button btnLedFail;

    private View layoutForeLight;
    private Button btnForeLightOk;
    private Button btnForeLightFail;

    private TextView txtPCBAPass;
    private TextView txtWifiInfo;
    private TextView txtBTInfo;

    private TextView txtSdcardInfo;

    private Button btnPower;
    private Button btnHome;
    private Button btnHall;
    private Button btnBack;
    private Button btnPlayMusic;

    private final int FLAG_KEY_POWER = 0x01;
    private final int FLAG_KEY_HOME = 0x02;
    private final int FLAG_KEY_HALL = 0x04;
    private final int FLAG_KEY_BACK = 0x08;

    private int flagKeyTest = FLAG_KEY_POWER | FLAG_KEY_HOME | FLAG_KEY_HALL | FLAG_KEY_BACK;

    private WifiManager mWifiManager;

    private BluetoothBondManager bluetoothBondManager;

    //wakeup
    private TextView txtWakeupTips;
    private TextView txtWakeupCount;
    private TextView txtWakeupCountDown;
    private TextView txtWakeupStatus;
    private Button btnWakeupTestStart;
    private static final int WAKE_UP_TIME_SECOND = 20;
    private static final int SUCCESS_WAKEUP_COUNT = 3;

    private int wakeupCount = 0;
    private int wakeupCountDown = WAKE_UP_TIME_SECOND;

    private final int HEADSET_PLUG = 0x01;
    private final int HEADSET_UNPLUG = 0x02;
    private int headsetEvent = (HEADSET_PLUG | HEADSET_UNPLUG);

    private FragmentES7210_MonoTest fragmentES7210;
    private OnBtnResultForES7210 onBtnResultForES7210 = new OnBtnResultForES7210() {
        @Override
        public void onBtnResultForES7210(boolean pass) {
            setTestItemPass(PCBATestItemEnum.wakeup, pass);
        }
    };

    @Override
    int getLayoutId() {
        return R.layout.activity_factory_pcba;
    }

    @Override
    void onInitView(@Nullable Bundle savedInstanceState) {

        txtWakeupTips = (TextView) findViewById(R.id.txtWakeupTips);
        txtWakeupCount = (TextView) findViewById(R.id.txtWakeupCount);
        txtWakeupCountDown = (TextView) findViewById(R.id.txtWakeupCountDown);
        txtWakeupStatus = (TextView) findViewById(R.id.txtWakeupStatus);
        btnWakeupTestStart = (Button) findViewById(R.id.btnWakeupTestStart);
        btnWakeupTestStart.setOnClickListener(this);
        txtWakeupTips.setText(getString(R.string.test_wakeup_tips, WAKE_UP_TIME_SECOND));

        btnTPFinger = (PCBATestBtnView) findViewById(R.id.btnTPFinger);
        btnTPElectric = (PCBATestBtnView) findViewById(R.id.btnTPElectric);
        btnTPFinger.setETP(false);
        btnTPElectric.setETP(true);

        btnLedOk = (Button) findViewById(R.id.btnLedOk);
        btnLedFail = (Button) findViewById(R.id.btnLedFail);

        btnForeLightOk = (Button) findViewById(R.id.btnForeLightOk);
        btnForeLightFail = (Button) findViewById(R.id.btnForeLightFail);

        layoutForeLight = findViewById(R.id.layoutForeLight);

        btnLedOk.setOnClickListener(this);
        btnLedFail.setOnClickListener(this);
        btnForeLightOk.setOnClickListener(this);
        btnForeLightFail.setOnClickListener(this);
        btnTPFinger.setOnClickListener(this);
        btnTPElectric.setOnClickListener(this);

        btnPower = (Button) findViewById(R.id.btnPower);
        btnHome = (Button) findViewById(R.id.btnHome);
        btnHall = (Button) findViewById(R.id.btnHall);
        btnBack = (Button) findViewById(R.id.btnBack);

        btnPlayMusic = (Button) findViewById(R.id.btnPlayMusic);
        btnPlayMusic.setOnClickListener(this);

        txtWifiInfo = (TextView) findViewById(R.id.txtWifiInfo);
        txtBTInfo = (TextView) findViewById(R.id.txtBTInfo);
        txtPCBAPass = (TextView) findViewById(R.id.txtPCBAPass);

        txtSdcardInfo = (TextView) findViewById(R.id.txtSdcardInfo);

        txtPCBAPass.setVisibility(View.INVISIBLE);

        DeviceAttr deviceAttr = DeviceAttr.getRunningDeviceAttr();
        if (!deviceAttr.hasHomeKey()) {
            btnHome.setVisibility(View.GONE);
            flagKeyTest &= ~FLAG_KEY_HOME;
        }

        if (!deviceAttr.hasBackKey()) {
            btnBack.setVisibility(View.GONE);
            flagKeyTest &= ~FLAG_KEY_BACK;
        }

        if (!deviceAttr.hasHallKey()) {
            btnHall.setVisibility(View.GONE);
            flagKeyTest &= ~FLAG_KEY_HALL;
        }

        if (!deviceAttr.hasETP()) {
            btnTPElectric.setVisibility(View.GONE);
        }

        if (!deviceAttr.hasForeLight()) {
            layoutForeLight.setVisibility(View.GONE);
        }

        if (!deviceAttr.hasTFCard()) {
            txtSdcardInfo.setVisibility(View.GONE);
        } else {
            updateUIWhileSDCardMounted();
        }

        updateBTInfo(false);
        updateWifiInfo(false);

        mWifiManager = getSystemService(WifiManager.class);

        bluetoothBondManager = new BluetoothBondManager(mContext);
        bluetoothBondManager.setEnabledListener(this);

        FTUtils.startFTFloat(mContext);

        if (!isWifiGotPermission()) {
            initWifiPermission();
        }

        initRecordPermission();

        updateRamAndRomResult();

        if (EinkProperty.isES7210Record()) {
            fragmentES7210 = new FragmentES7210_MonoTest();
            fragmentES7210.setOnBtnResultForES7210(onBtnResultForES7210);
            ViewGroup container = (ViewGroup) findViewById(R.id.container);
            container.removeAllViews();

            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.container, fragmentES7210)
                    .commit();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        EinkProperty.setEinkFactoryTestEnabled(true);

        showDialogForHeadsetTest();
        registerHeadsetPlugReceiver();

        registerWifiReceiver(mContext);

        if (isWifiEnabled()) {
            updateWifiInfo(true);
        } else {
            openWiFi();
        }

        bluetoothBondManager.registerBTReceiver();
        if (bluetoothBondManager.isBluetoothEnabled()) {
            updateBTInfo(true);
        } else {
            bluetoothBondManager.openBluetooth();
        }

        startLedCtrl();

        registerSdcardReceiver();

        clearWakeupTxt();

//        startTestPlaySound();

    }

    @Override
    protected void onPause() {
        super.onPause();
        DebugLog.e("onPause");

        EinkProperty.setEinkFactoryTestEnabled(false);

        unregisterHeadsetPlugReceiver();

        unregisterWifiReceiver(mContext);
        closeWiFi();

        bluetoothBondManager.unregisterBTReceiver();
        bluetoothBondManager.closeBluetooth();

        stopLedCtrl();

        stopTestPlaySound();

        unregisterSdcardReceiver();

        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopWakeupTest();
    }

    private void initRecordPermission() {
        //如果无权限就申请然后回调，如果有权限就执行录音监听
        if (!isRecordGotPermission()) {

            //同时申请多个权限
            PermissionManager.getInstance(getApplicationContext()).execute(this,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.WRITE_SETTINGS,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
    }

    private boolean isRecordGotPermission() {

        return (ContextCompat.checkSelfPermission(mContext, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED
        );

    }

    private boolean isWifiGotPermission() {

        return !((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED));

    }

    private void initWifiPermission() {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            //同时申请多个权限
            PermissionManager.getInstance(getApplicationContext()).execute(this,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION);

        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionManager.getInstance(getApplicationContext()).
                onRequestPermissionsResult(requestCode, permissions, grantResults);

    }

    /////////////////////////////////////////////////////////
    // rom and ram
    ////////////////////////////////////////////////////////
    private void updateRamAndRomResult() {

        View viewRam = findViewById(R.id.txtRam);
        View viewRom = findViewById(R.id.txtRom);
        if (viewRam instanceof TextView) {
            TextView ram = (TextView) viewRam;
            String ramString = getString(R.string.ram_test_result, UsefulUtils.getRamNominalSize(), getRamResult());
            ram.setText(getSpannableString(ramString));
        }

        if (viewRom instanceof TextView) {
            TextView rom = (TextView) viewRom;
            String romString = getString(R.string.rom_test_result, UsefulUtils.getRomNominalSize(), getRomResult());
            rom.setText(getSpannableString(romString));
        }
    }

    private String getRamResult() {
        BigDecimal definedRamSize = new BigDecimal(UsefulUtils.getDefinedRamSize());
        BigDecimal realRamSize = new BigDecimal(UsefulUtils.getRamTotalSize());
        boolean pass = realRamSize.compareTo(definedRamSize) > 0;
        String result = getString(pass ? R.string.test_result_pass : R.string.test_result_fail);
        setTestItemPass(PCBATestItemEnum.ram, pass);
        return result;
    }

    private String getRomResult() {
        BigDecimal definedRomSize = new BigDecimal(UsefulUtils.getDefinedRomSize());
        BigDecimal realRomSize = new BigDecimal(UsefulUtils.getRomTotalSize());
        boolean pass = realRomSize.compareTo(definedRomSize) > 0;
        String result = getString(pass ? R.string.test_result_pass : R.string.test_result_fail);
        setTestItemPass(PCBATestItemEnum.rom, pass);

        return result;
    }


    ////////////////////////////////////////////////////////

    private boolean isWifiEnabled() {
        return null != mWifiManager && mWifiManager.isWifiEnabled();
    }
    /**
     * 打开Wifi
     */
    private void openWiFi() {
        if (!isWifiEnabled() && null != mWifiManager) {
            mWifiManager.setWifiEnabled(true);
        }
    }

    /**
     * 关闭Wifi
     */
    private void closeWiFi() {
        if (isWifiEnabled() && null != mWifiManager) {
            mWifiManager.setWifiEnabled(false);
        }
    }

    private void updateBTInfo(boolean enabled) {

        String status = getString(R.string.status_off);
        String result = getString(R.string.test_result_fail);
        if (enabled) {
            status = getString(R.string.status_on);
            result = getString(R.string.test_result_pass);
        }
        String infoString = getString(R.string.pcba_bt_status, status, result);

        txtBTInfo.setText(getSpannableString(infoString));

        setTestItemPass(PCBATestItemEnum.bluetooth, enabled);

    }

    private void updateWifiInfo(boolean enabled) {

        String status = getString(R.string.status_off);
        String result = getString(R.string.test_result_fail);
        if (enabled) {
            status = getString(R.string.status_on);
            result = getString(R.string.test_result_pass);
        }
        String infoString = getString(R.string.pcba_wifi_status, status, result);

        txtWifiInfo.setText(getSpannableString(infoString));

        setTestItemPass(PCBATestItemEnum.wifi, enabled);

    }

    @NonNull
    private SpannableString getSpannableString(String infoString) {
        final SpannableString msp = new SpannableString(infoString);
        String resultSearch = getString(R.string.ft_use_result_for_search);
        int index = infoString.indexOf(resultSearch);
        if (index > 0) {
            msp.setSpan(new RelativeSizeSpan(1.2f), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            msp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            msp.setSpan(new UnderlineSpan(), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return msp;
    }

    private void startLedCtrl() {
        getHandler().sendEmptyMessage(MSG_LED_CTRL);
    }
    private void stopLedCtrl() {
        getHandler().removeMessages(MSG_LED_CTRL);
        LedCtrl.setLed(false, LedCtrl.LedAttr.led_green, LedCtrl.LedAttr.led_red);
    }

    ViewDialogFragment dialogWhenHeadsetUnplug;
    private void dismissDialogForHeadsetTest() {

        if (dialogWhenHeadsetUnplug != null) {
            dialogWhenHeadsetUnplug.dismiss();
            dialogWhenHeadsetUnplug = null;
        }
    }

    private void showDialogForHeadsetTest() {

        if (dialogWhenHeadsetUnplug == null) {
            final String title = getString(R.string.headset_event);
            final String msg = getString(R.string.headset_event_plug_unplug);
            dialogWhenHeadsetUnplug = ViewDialogFragment.newInstance(title, msg, false);
        }

        if (!dialogWhenHeadsetUnplug.isShowing()) {
            dialogWhenHeadsetUnplug.show(getFragmentManager());
        }

    }

    private void registerHeadsetPlugReceiver() {
        //发送广播检测耳机插入状态
        IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
        registerReceiver(headsetPlugReceiver, filter);
    }

    private void unregisterHeadsetPlugReceiver() {
        unregisterReceiver(headsetPlugReceiver);
    }


    private BroadcastReceiver headsetPlugReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();

            if (action != null && action.equals(Intent.ACTION_HEADSET_PLUG)) {
                if (intent.hasExtra("state")) {

                    boolean unplug = (intent.getIntExtra("state", 0) == 0);
                    DebugLog.e("unplug = " + unplug);


                    if (unplug) {

                        headsetEvent &= ~HEADSET_UNPLUG;
                        stopTestPlaySound();

                    } else {

                        headsetEvent &= ~HEADSET_PLUG;
                        startTestPlaySound();

                    }

                    if (headsetEvent == 0 ) {
                        dismissDialogForHeadsetTest();
                        setTestItemPass(PCBATestItemEnum.headset, true);
                    }
                }
            }
        }
    };

    public void registerWifiReceiver(Context context) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        context.getApplicationContext().registerReceiver(wifiReceiver, filter);
    }

    public void unregisterWifiReceiver(Context context) {
        context.getApplicationContext().unregisterReceiver(wifiReceiver);
    }

    private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action == null) {
                return;
            }

            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                switch (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)) {
                    case WifiManager.WIFI_STATE_ENABLING:
                        break;
                    case WifiManager.WIFI_STATE_ENABLED:
                        DebugLog.e("wifi WIFI_STATE_ENABLED ");

                        updateWifiInfo(true);
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                    case WifiManager.WIFI_STATE_DISABLED:
                        DebugLog.e("wifi disabled ");
                        updateWifiInfo(false);
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                    default:
                        break;
                }
            }

        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_HOME) {

            btnHome.setSelected(true);

            return true;

        } else if (keyCode == KeyEvent.KEYCODE_BACK) {

            btnBack.setSelected(true);

            return true;

        } else if (keyCode == KeyEvent.KEYCODE_POWER) {

            btnPower.setSelected(true);
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_SLEEP) {

            btnHall.setSelected(true);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {

        boolean ret = true;

        if (keyCode == KeyEvent.KEYCODE_HOME) {

            btnHome.setSelected(false);
            btnHome.setText(getNewTextForBtn(btnHome, getResources().getString(R.string.test_ok)));

            flagKeyTest &= ~FLAG_KEY_HOME;

        } else if (keyCode == KeyEvent.KEYCODE_BACK) {

            btnBack.setSelected(false);
            btnBack.setText(getNewTextForBtn(btnBack, getResources().getString(R.string.test_ok)));

            flagKeyTest &= ~FLAG_KEY_BACK;

        } else if (keyCode == KeyEvent.KEYCODE_POWER) {

            btnPower.setSelected(false);
            btnPower.setText(getNewTextForBtn(btnPower, getResources().getString(R.string.test_ok)));

            flagKeyTest &= ~FLAG_KEY_POWER;

        } else if (keyCode == KeyEvent.KEYCODE_SLEEP) {

            btnHall.setSelected(false);
            btnHall.setText(getNewTextForBtn(btnHall, getResources().getString(R.string.test_ok)));

            flagKeyTest &= ~FLAG_KEY_HALL;

        } else {

            ret = false;
        }

        if (ret && flagKeyTest == 0) {
            setTestItemPass(PCBATestItemEnum.key, true);
        }

        return ret || super.onKeyUp(keyCode, event);
    }

    private String getNewTextForBtn(View btn, String test_status) {

        if (!(btn instanceof TextView)) {
            return "";
        }
        TextView txt = (TextView) btn;
        String text = txt.getText().toString();
        String arrow = getResources().getString(R.string.arrow);
        String[] rmStatus = text.split(arrow);
        if (rmStatus.length > 1) {
            text = rmStatus[0];
        }
        return (text + arrow + test_status);
    }


    private void setTestItemPass(PCBATestItemEnum item, boolean pass) {
        item.setPass(pass);
        updatePCBAPassTxt();
    }

    private void updatePCBAPassTxt() {
        boolean pass = true;

        DeviceAttr deviceAttr = DeviceAttr.getRunningDeviceAttr();

        for (PCBATestItemEnum itemEnum : PCBATestItemEnum.values()) {

            if (itemEnum == PCBATestItemEnum.tp_eletric && !deviceAttr.hasETP()) {
                continue;
            }

            if (itemEnum == PCBATestItemEnum.sdcard && !deviceAttr.hasTFCard()) {
                continue;
            }

            if (itemEnum == PCBATestItemEnum.fore_light && !deviceAttr.hasForeLight()) {
                continue;
            }

            if (!itemEnum.isPass()) {
                pass = false;
                DebugLog.e("itemEnum = " + itemEnum);
                break;
            }
        }
        txtPCBAPass.setVisibility(pass ? View.VISIBLE : View.INVISIBLE);

        if (pass) {
            FactoryTestItemsEnum.pcba.setResult(mContext, getString(R.string.test_result_pass));
            FTFloatWindowService.setPCBABtnShow(false);
        }

    }

    private final static int MSG_LED_CTRL = 100;
    private final static int PERIOD_LED_CTRL = 2000;//1s

    private static final int MSG_WAKEUP_COUNT_DOWN = 1000;
    private static final int PERIOD_WAKEUP_COUNT_DOWN = 1000;


    private int ledOnCount = 0;
    @Override
    void onHandleMessage(Handler handler, Message msg) {

        switch (msg.what) {
            case MSG_LED_CTRL:
                if (++ledOnCount > 10000) {
                    ledOnCount = 0;
                }
                LedCtrl.setLed((0 == (ledOnCount % 2)), LedCtrl.LedAttr.led_green);
                LedCtrl.setLed(!(0 == (ledOnCount % 2)), LedCtrl.LedAttr.led_red);

                if (DeviceAttr.getRunningDeviceAttr().hasForeLight()) {
                    ForeLightCtrl.getForeLightCtrl().setColdLightBrightness(mContext, (0 == (ledOnCount % 2)) ? ForeLightCtrl.MAX_BRIGHTNESS : 0);
                    ForeLightCtrl.getForeLightCtrl().setWarmLightBrightness(mContext, !(0 == (ledOnCount % 2)) ? ForeLightCtrl.MAX_BRIGHTNESS : 0);
                }

                handler.sendEmptyMessageDelayed(msg.what, PERIOD_LED_CTRL);

                break;

            case MSG_WAKEUP_COUNT_DOWN:
                updateCountdown();
                break;
        }
    }

    @Override
    public void onClick(View v) {

        boolean selected = true;
        if (v == btnLedOk) {

            setTestItemPass(PCBATestItemEnum.led, true);

        } else if (v == btnLedFail) {

            setTestItemPass(PCBATestItemEnum.led, false);

        } else if (v == btnForeLightOk) {

            setTestItemPass(PCBATestItemEnum.fore_light, true);

        } else if (v == btnForeLightFail) {

            setTestItemPass(PCBATestItemEnum.fore_light, false);

        } else if (v == btnTPFinger) {

            selected = false;
            btnTPFinger.setText(getNewTextForBtn(v, getResources().getString(R.string.test_ok)));
            setTestItemPass(PCBATestItemEnum.tp_finger, true);

        } else if (v == btnTPElectric) {

            selected = false;

            btnTPElectric.setText(getNewTextForBtn(v, getResources().getString(R.string.test_ok)));
            setTestItemPass(PCBATestItemEnum.tp_eletric, true);

        } else if (v == btnWakeupTestStart) {

            selected = false;
            startWakeupTest();

        } else if (v == btnPlayMusic) {

            selected = false;
            if (mediaPlayer == null) {
                startTestPlaySound();
            } else {
                stopTestPlaySound();
            }

        } else {

            selected = false;

        }
        v.setSelected(selected);

    }

    @Override
    public void onBluetoothEnabled(boolean enabled) {

        updateBTInfo(enabled);

    }


    ///////////////
    // sdcard start
    ///////////////
    private String getSDCardPath() {
        if (!isSDCardInserted()) {
            return "";
        }

        StorageManager sm = getSystemService(StorageManager.class);

        if (sm == null) {
            return "";
        }

        List<StorageVolume> volList = sm.getStorageVolumes();
        if (volList == null || volList.isEmpty()) {
            return "";
        }

        for (StorageVolume vol : volList) {
            if (vol.getState().equals(Environment.MEDIA_MOUNTED)
                    && vol.getDescription(mContext).contains("SD")) {

                try {
                    Method getPath = StorageVolume.class.getMethod("getPath");
                    String path = (String) getPath.invoke(vol);
                    DebugLog.i( "StoragePath--->" + path);

                    return path;
//
//                    StatFs stat = new StatFs(path);
//
//                    Log.e(TAG, "total size = " + Formatter.formatFileSize(this, stat.getTotalBytes()));
//                    Log.e(TAG, "free size = " + Formatter.formatFileSize(this, stat.getFreeBytes()));

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }

        return "";

    }
    private boolean isSDCardInserted() {

        StorageManager sm = getSystemService(StorageManager.class);

        if (sm == null) {
            return false;
        }

        List<StorageVolume> volList = sm.getStorageVolumes();
        if (volList == null || volList.isEmpty()) {
            return false;
        }

        for (StorageVolume vol : volList) {

           DebugLog.i("vol state = " + vol.getState() + ", desc = " + vol.getDescription(mContext));

        }

        for (StorageVolume vol : volList) {
            if (vol.getState().equals(Environment.MEDIA_MOUNTED)
                    && vol.getDescription(mContext).contains("SD")) {

                return true;
            }
        }

        return false;

    }

    private void updateUIWhileSDCardMounted() {

        txtSdcardInfo.setText(R.string.sdcard_test_ejected);
        if (!isSDCardInserted()) {
            return;
        }

        String path = getSDCardPath();
        if (TextUtils.isEmpty(path)) {
            return;
        }

        StatFs stat = new StatFs(path);

        String infoString = mContext.getString(R.string.sdcard_test_inserted_info,
                Formatter.formatFileSize(mContext, stat.getTotalBytes()),
                Formatter.formatFileSize(mContext, stat.getFreeBytes()),
                getString(R.string.test_result_pass));

        SpannableString msp = getSpannableString(infoString);

        txtSdcardInfo.setText(msp);

    }

    private IntentFilter getIntentFilterOfSDCard() {
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);

        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);

        intentFilter.addAction(Intent.ACTION_MEDIA_REMOVED);
        intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);

        intentFilter.addDataScheme("file");

        return intentFilter;
    }

    private void registerSdcardReceiver() {
        if (!DeviceAttr.getRunningDeviceAttr().hasTFCard()) {
            return;
        }

        mContext.registerReceiver(sdcardReceiver, getIntentFilterOfSDCard());

    }

    private void unregisterSdcardReceiver() {
        if (!DeviceAttr.getRunningDeviceAttr().hasTFCard()) {
            return;
        }
        mContext.unregisterReceiver(sdcardReceiver);
    }


    private final BroadcastReceiver sdcardReceiver =  new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action == null) {
                return;
            }
            DebugLog.e("sdcard action = " + action + ", intent.getData() = " + intent.getData());

            updateUIWhileSDCardMounted();

        }
    };

    ///////////////
    // sdcard end
    ///////////////

    //wakeup
    private void clearWakeupTxt() {
        txtWakeupCount.setText("");
        txtWakeupCountDown.setText("");
        txtWakeupStatus.setText("");
    }

    private void startWakeupTest() {

        if (EinkProperty.isES7210Record()) {
            return;
        }

        if (!btnWakeupTestStart.isEnabled()) {
            // 已经开始唤醒测试了
            return;
        }
        btnWakeupTestStart.setEnabled(false);

        startRecognition();
        wakeupCount = 0;
        wakeupCountDown = WAKE_UP_TIME_SECOND;
        txtWakeupCount.setText(getString(R.string.wakeup_success_count, wakeupCount, (SUCCESS_WAKEUP_COUNT - wakeupCount)));
        updateCountdown();

    }

    private void stopWakeupTest() {
        if (EinkProperty.isES7210Record()) {
            return;
        }
        stopRecognition();
        getHandler().removeMessages(MSG_WAKEUP_COUNT_DOWN);

        btnWakeupTestStart.setEnabled(true);
    }

    private void startRecognition() {

        setWakeupEnabled(true);

        txtWakeupStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.wakeup_status_doing)));

    }

    private void stopRecognition() {
        setWakeupEnabled(false);
    }

    private void handleRecognition() {

        txtWakeupCount.setText(getString(R.string.wakeup_success_count, wakeupCount, (SUCCESS_WAKEUP_COUNT - wakeupCount)));

        if (wakeupCount >= SUCCESS_WAKEUP_COUNT) {
            txtWakeupStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_pass)));
            setTestItemPass(PCBATestItemEnum.wakeup, true);

            stopWakeupTest();

            return;
        }
    }

    private void updateCountdown() {

        if (wakeupCountDown <= 0) {
            if (wakeupCount < SUCCESS_WAKEUP_COUNT) {
                txtWakeupStatus.setText(getString(R.string.wakeup_test_status, getString(R.string.test_result_fail)));
                setTestItemPass(PCBATestItemEnum.wakeup, false);
                stopWakeupTest();
            }

            return;
        }

        int count = getWakeupCountByParseWakeupInfo(readWakeupInfo());
        if (count >= 0) {
            wakeupCount = count;
            handleRecognition();
        }

        wakeupCountDown--;
        txtWakeupCountDown.setText(getString(R.string.wakeup_test_countdown, wakeupCountDown));

        getHandler().sendEmptyMessageDelayed(MSG_WAKEUP_COUNT_DOWN, PERIOD_WAKEUP_COUNT_DOWN);
    }

    //wakeup end

    ///////////
    private final static String PATH_WAKEUP = "/sys/class/xfm10213/wakeup";
    private String readWakeupInfo() {
        return FileReadWrite.readFileByLines(PATH_WAKEUP);
    }

    private boolean hasOK(String wakeupInfo) {
        return (wakeupInfo.toUpperCase().contains("OK"));
    }

    private int getWakeupCountByParseWakeupInfo(String wakeupInfo) {
        if (TextUtils.isEmpty(wakeupInfo)) {
            return -1;
        }
        if (!hasOK(wakeupInfo)) {
            return -1;
        }
        String[] parseString = wakeupInfo.replace(".", "").split("=");

        DebugLog.e("wakeupInfo = " + wakeupInfo);

        if (parseString.length == 2
                && !TextUtils.isEmpty(parseString[1])
                && TextUtils.isDigitsOnly(parseString[1])) {

            return Integer.decode(parseString[1]);

        }

        return 0;
    }

    private void setWakeupEnabled(boolean enabled) {
        FileReadWrite.writeStringToFile(PATH_WAKEUP, enabled ? "1" : "0");
    }

    //play music
    private MediaPlayer mediaPlayer;
    private void stopTestPlaySound() {

        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();//回收资源
            mediaPlayer = null;
        }

        btnPlayMusic.setText(R.string.pcba_play_music_start);
    }

    private void startTestPlaySound() {
        if (mediaPlayer != null) {
            stopTestPlaySound();
        }
        try {
            mediaPlayer = MediaPlayer.create(getContext(), R.raw.music_test_channel);;
            mediaPlayer.setLooping(true);//这种这个后, setOnCompletionListener不能被调用了.
            mediaPlayer.start();
            DebugLog.e("mediaPlayer start ");

        } catch (Exception e) {
            DebugLog.e("exception e = " + e.getMessage());
        }

        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                DebugLog.e("onError, what = " + what + ", extra = " + extra);
                startTestPlaySound();
                return true;
            }
        });

        btnPlayMusic.setText(R.string.pcba_play_music_stop);

    }

    ////////////////////////////////////////////
    private enum PCBATestItemEnum {
        led,
        headset,
        wakeup,
        wifi,
        bluetooth,
        key,
        tp_finger,
        tp_eletric,
        sdcard,
        fore_light,
        ram,
        rom,
        ;
        private boolean pass;

        public boolean isPass() {
            return pass;
        }

        public void setPass(boolean pass) {
            this.pass = pass;
        }
    }

}
